using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using System.Reactive.Subjects;
using System.Reactive.Disposables;

namespace ReactiveGameDemo
{
    public class GameObject : DrawableGameComponent
    {
        public static Random randGen = new Random();
        public CompositeDisposable subscriptions;

        // user input
        public static Subject<Keys> keyPresses = new Subject<Keys>();
        public static Subject<Keys> keyReleases = new Subject<Keys>();

        // collision
        public Subject<GameObject> collisionEnter;
        public Subject<GameObject> collisionExit;
        public List<GameObject>    wasCollidingWith;
        public List<GameObject>    isCollidingWith;
        public Vector2 position;
        public float rotation;
        public float size;

        // graphics
        protected string spriteName;
        protected Texture2D image;
        protected Vector2 center;
        protected float scale;
        protected Vector2 Forward {
            get { return new Vector2((float)Math.Cos(rotation), (float)Math.Sin(rotation)); }
            set { rotation = (float)Math.Atan2(value.Y, value.X); }
        }

        public GameObject(Game game, string spriteName) : base(game)
        {
            this.spriteName = spriteName;
            wasCollidingWith = new List<GameObject>();
            isCollidingWith = new List<GameObject>();
            game.Components.Add(this);
        }

        public override void Initialize()
        {
            scale = 1;
            base.Initialize();

            subscriptions = new CompositeDisposable();
            collisionEnter = new Subject<GameObject>();
            collisionExit = new Subject<GameObject>();
            position = new Vector2(randGen.Next(GraphicsDevice.Viewport.Width),
                                   randGen.Next(GraphicsDevice.Viewport.Height));
            rotation = 0;
        }

        protected override void LoadContent()
        {
            image = Game.Content.Load<Texture2D>(spriteName);
            center = new Vector2(image.Width, image.Height) / 2;
            size = Math.Min(center.X, center.Y) * scale;
            base.LoadContent();
        }

        public override void Draw(GameTime gameTime)
        {
            rxGame.spriteBatch.Draw(image, position, null, Color.White, rotation, center, scale, SpriteEffects.None, 0.5f);
            base.Draw(gameTime);
        }
    }
}
